package com.pjmike.netty.protocol.message.decoder;

import com.pjmike.netty.protocol.message.packet.request.AuthRequestPacket;
import com.pjmike.netty.protocol.message.packet.request.HeartbeatRequestPacket;
import com.pjmike.netty.protocol.message.command.Command;
import com.pjmike.netty.utils.Crc32Util;
import com.pjmike.netty.utils.StringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 自定义解码器
 *
 * @author pjmike
 * @create 2018-10-24 20:19
 */
@Slf4j
public class HeartbeatDecoder extends ByteToMessageDecoder {
    //心跳报文长度
    private static int MESSAGE_LENGTH = 27;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (!check(in)) {
            log.error("心跳检验到非法报文，{}", StringUtil.getByteBufByteHexString(in));
            return;
        }
        in.markReaderIndex();
        short header = in.readUnsignedByte();
        int protocolNo = in.readUnsignedShort();
        if (protocolNo == Command.HEARTBEAT_REQUEST) {
            HeartbeatRequestPacket heartbeatRequestPacket = new HeartbeatRequestPacket();
            heartbeatRequestPacket.setBt(header);
            heartbeatRequestPacket.setProtocolNo(protocolNo);
            byte[] bytes = new byte[15];
            in.readBytes(bytes);
            heartbeatRequestPacket.setSbbh(new String(bytes, 0, 15));
            heartbeatRequestPacket.setSjcd(in.readUnsignedInt());
            heartbeatRequestPacket.setSjjy(in.readUnsignedInt());
            heartbeatRequestPacket.setBw(in.readUnsignedByte());
            log.info("获取到心跳报文，内容：{}", heartbeatRequestPacket.toString());
            out.add(heartbeatRequestPacket);
        } else {
            in.resetReaderIndex();
            ByteBuf frame = in.retainedDuplicate();
            out.add(frame);
            in.skipBytes(in.readableBytes());
        }
    }

    /**
     * @return boolean
     * @Author bj
     * @Description //校验报文
     * @Date 11:54 2021/1/10
     * @Param [in]
     **/
    private boolean check(ByteBuf in) {
        return Crc32Util.checkMessageFromByteBuf(in);
    }
}
